﻿/* ********************************************************************************
 * 名称：SysRole_RepositoryService
 * 描述：系统角色表  仓储服务接口实现类（本类通过CodeSmith软件生成生成）
 * 创建人：HFL
 * 创建日期：2020-06-01 17:48:55
 * 修改人：
 * 修改日期：
 * *******************************************************************************/
using WPay.Domain.MainModule.Interface.RepositoryServices;
using WPay.Domain.Model.DTOs;
using WPay.Domain.Model.Entities;
using WPay.Infrastructure.Repository.Base;
using WPay.Infrastructure.Repository.DapperCore;
using WPay.Infrastructure.Unity;
using Dapper;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using WPay.Domain;
using Model.PageModel;
using Model.DTO;
using WPay.Infrastructure.EFCore;
using System.Linq;
using Model.DTO.Manager;
using System.Data.Entity;

namespace WPay.Infrastructure.Repository.MainModule
{
    /// <summary>
    /// 系统角色表 仓储服务接口实现类
    /// </summary>
    public class SysRole_RepositoryService : RepositoryBase, ISysRole_RepositoryService
    {
        /// <summary>
        /// 查询SQL语句
        /// </summary>
        private readonly string querySql = @"select ID,RoleName,Memo,OrderID,IsDeleted,CpnId from SysRole where 1=1";
        /// <summary>
        /// 查询数据条数SQL语句
        /// </summary>
        private readonly string queryCountSql = @"select count(1) from SysRole where 1=1";
        /// <summary>
        /// 新增SQL语句
        /// </summary>
        private readonly string addSql = @"insert into SysRole(ID,RoleName,Memo,OrderID,IsDeleted,CpnId) values (@ID,@RoleName,@Memo,@OrderID,@IsDeleted,@CpnId)";
        /// <summary>
        /// 修改所有字段SQL语句
        /// </summary>
        private readonly string editSql = @"update SysRole set RoleName=@RoleName,Memo=@Memo,OrderID=@OrderID,IsDeleted=@IsDeleted,CpnId=@CpnId where 1=1";
        /// <summary>
        /// 表主键where条件SQL语句
        /// </summary>
        private readonly string whereByPrimaryKey = @" and ID=@ID";

        private readonly IEfCore_RepositoryService _efCore_RepositoryService;
        private Entities db;
        public SysRole_RepositoryService(IEfCore_RepositoryService efCore_RepositoryService)
        {
            _efCore_RepositoryService = efCore_RepositoryService;
            db = _efCore_RepositoryService.DbContext();
        }

        #region 由软件生成，禁止修改，若需要扩展，请在下方进行扩展

        /// <summary>
        /// 根据主键获取系统角色表资料信息
        /// </summary>
        /// <param name="_iD"></param>
        /// <returns>返回单个系统角色表数据实体</returns>
        public SysRole Get(string _iD)
        {
            string sql = querySql + whereByPrimaryKey;
            DynamicParameters param = new DynamicParameters();
            param.Add("ID", _iD);
            return base.QueryBySql<SysRole>(sql, param);
        }

        /// <summary>
        /// 获取所有记录
        /// </summary>
        /// <param name="_cpnID">企业代码</param>
        /// <returns>返回系统角色表数据集合</returns>
        public List<SysRole> GetAll(string _cpnID)
        {
            return base.QueryListBySql<SysRole>(querySql + " and CpnID=@CpnID", new { CpnID = _cpnID });
        }

        /// <summary>
        /// 获取所有记录
        /// </summary>
        /// <param name="_param">查询条件字典，其中key必须使用字段名</param>
        /// <returns>返回系统角色表数据集合</returns>
        public List<SysRole> GetAll(Hashtable _param)
        {
            //查询SQL语句组装
            string sql = querySql + base.GetQueryConditions(_param);
            //封装参数
            DynamicParameters dynamicParam = new DynamicParameters();
            foreach (string key in _param.Keys)
            {
                dynamicParam.Add(key, _param[key]);
            }

            return base.QueryListBySql<SysRole>(sql, dynamicParam);
        }

        /// <summary>
        /// 按照分页条件查询数据集
        /// </summary>
        /// <param name="_param">查询条件字典，其中key必须使用字段名</param>
        /// <param name="_pageIndex">查询页码，从1开始，必传</param>
        /// <param name="_pageSize">每页查询数据条数，必传</param>
        /// <param name="_sort">排序列名，若要降序请用列名+" DESC"，必传</param>
        /// <param name="_pageCount">返回总页码数</param>
        /// <param name="_dataCount">返回总数据条数</param>
        /// <returns>返回系统角色表数据集合</returns>
        public List<SysRole> GetByPage(Hashtable _param, int _pageIndex, int _pageSize, string _sort, out int _pageCount, out int _dataCount)
        {
            if (_pageIndex == 0 || _pageSize == 0 || string.IsNullOrWhiteSpace(_sort))
            {
                _dataCount = 0;
                _pageCount = 0;
                return null;
            }
            //封装参数
            DynamicParameters dynamicParam = new DynamicParameters();
            foreach (string key in _param.Keys)
                dynamicParam.Add(key, _param[key]);
            //组装计数sql语句
            string countSql = queryCountSql + base.GetQueryConditions(_param);
            _dataCount = base.QueryScalarBySql<Int32>(countSql, dynamicParam);//获取总数据条数
            _pageCount = (_dataCount + _pageSize - 1) / _pageSize;//总页数 =  (数据总条数 + 每页显示条数 - 1) / 每页显示条数
            if (_dataCount == 0)
            {
                return new List<SysRole>();
            }
            //组装分页查询语句
            string sql = querySql + base.GetQueryConditions(_param, _pageIndex, _pageSize, _sort);

            return base.QueryListBySql<SysRole>(sql, dynamicParam);
        }

        /// <summary>
        /// 插入系统角色表数据
        /// </summary>
        /// <param name="_sysRole">需要插入的系统角色表数据实体</param>
        /// <returns>返回影响数据行数</returns>
        public int Add(SysRole _sysRole)
        {
            return base.ExecuteBySql(addSql, _sysRole);
        }

        /// <summary>
        /// 批量插入系统角色表数据
        /// </summary>
        /// <param name="_sysRoleList">需要插入的系统角色表数据集合</param>
        /// <returns>返回影响数据行数</returns>
        public int Add(List<SysRole> _sysRoleList)
        {
            return base.BulkInsert(_sysRoleList);
        }

        /// <summary>
        /// 根据主键更新系统角色表数据
        /// </summary>
        /// <param name="_sysRole">需要更新的系统角色表数据实体</param>
        /// <returns>返回影响数据行数</returns>
        public int Update(SysRole _sysRole)
        {
            return base.ExecuteBySql(editSql + whereByPrimaryKey, _sysRole);
        }

        /// <summary>
        /// 根据主键更新系统角色表指定字段
        /// </summary>
        /// <param name="_sysRole">需要更新的系统角色表数据实体</param>
        /// <param name="_updateProNames">需要更新的字段名</param>
        /// <returns>返回影响数据行数</returns>
        public int Update(SysRole _sysRole, params string[] _updateProNames)
        {
            string sql = @"update SysRole set ";
            //主键值在修改时，禁止为空
            if (_sysRole.ID == default(string))
                return 0;
            sql += base.GetUpdateSet(_updateProNames);
            return base.ExecuteBySql(sql + whereByPrimaryKey, _sysRole);
        }

        #endregion

        /*业务扩展代码*/
        #region 业务扩展代码
        /// <summary>
        /// 获取角色列表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="rows"></param>
        /// <param name="roleParms"></param>
        /// <returns></returns>

        public EntityList<RoleDTO> GetRoleList(int page, int rows, LoginUserDTO data, RoleParms roleParms)

        {
            Dictionary<string, string> sort = new Dictionary<string, string>() { { "OrderID", "ASC" } };

            var wheres = PredicateBuilder.True<SysRole>();
            if (data.CpnId != "system")
            {
                wheres = wheres.And(x => x.CpnId == data.CpnId);
            }
            if (!string.IsNullOrEmpty(roleParms.RoleName))
            {
                wheres = wheres.And(x => x.RoleName.Contains(roleParms.RoleName));
            }
            var dbset = db.Set<SysRole>();
            var query = (from a in dbset.Where(x => !x.IsDeleted).Where(wheres)
                         select new RoleDTO()
                         {
                             ID = a.ID,
                             RoleName = a.RoleName,
                             Memo = a.Memo,
                             OrderID = a.OrderID,
                             ImageUrl = a.ImageUrl,
                             CpnId = a.CpnId
                         });
            var list = _efCore_RepositoryService.FindAllAsQuery<RoleDTO>(_efCore_RepositoryService.DataSort(query, sort), page, rows);
            var roleids = list.Data.Select(x => x.ID).Distinct().ToList();
            var lcount = (from a in db.MngrRole.Where(x => roleids.Contains(x.RoleId) && x.IsDeleted == false)
                          join m in db.MngrBaseInfo.Where(x => x.IsDeleted == false) on a.MemberId equals m.ID
                          select a).GroupBy(x => x.RoleId)
                            .Select(g => new
                            {
                                RoleId = g.Key,
                                MemCount = g.Count(),
                            }).ToList();
            var rlist = (from a in list.Data
                         join b in lcount on a.ID equals b.RoleId into dtable
                         from g in dtable.DefaultIfEmpty()
                         select new RoleDTO()
                         {
                             ID = a.ID,
                             RoleName = a.RoleName,
                             Memo = a.Memo,
                             OrderID = a.OrderID,
                             ImageUrl = a.ImageUrl,
                             MemCount = g != null ? g.MemCount : 0,
                             CpnId=a.CpnId
                         }).ToList();
            list.Data = rlist;
            return list;
        }

        public List<RoleDTO> GetRoleList()

        {
            // var data = Common.SessionHelper.Get<ManagementUsr>("ManagementUsr");
            var wheres = PredicateBuilder.True<SysRole>();
            //if (data.CpnId != "system")
            //{
            //    wheres = wheres.And(x => x.CpnId == data.CpnId);
            //}
            //wheres = wheres.And(x => x.CpnId == data.CpnId);
            var dbset = db.Set<SysRole>();
            var query = (from a in dbset.Where(wheres)
                         select new RoleDTO()
                         {
                             ID = a.ID,
                             RoleName = a.RoleName,
                             Memo = a.Memo,
                             OrderID = a.OrderID,
                             ImageUrl = a.ImageUrl,
                         });
            return query.ToList();
        }
        /// <summary>
        /// 加载角色信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<RoleListDTO> LoadMangerRoleList(string id, LoginUserDTO data)
        {
            var wheres = PredicateBuilder.True<SysRole>();
            //if (data.CpnId != "system")
            //{
            //    wheres = wheres.And(x => x.CpnId == data.CpnId);
            //}
            wheres = wheres.And(x => x.CpnId == data.CpnId);
            if (string.IsNullOrEmpty(id))//Add
            {
                var allroes = (from roles in db.SysRole.Where(wheres)
                               orderby roles.OrderID ascending
                               where !roles.IsDeleted
                               select new RoleListDTO()
                               {

                                   ID = roles.ID,
                                   RoleName = roles.RoleName,
                                   Ischeck = false

                               }).ToList();
                return allroes;
            }
            else//Editor
            {
                var dbset = db.Set<SysRole>();
                //var Roles = (from mamager in db.MngrBaseInfo.Where(x => x.ID == id) where !mamager.IsDeleted 

                //             select  new MangRoleList
                //             {
                //                 Roles = roles
                //             }).FirstOrDefault();
                var allrole = (from role in dbset.Where(x => !x.IsDeleted).Where(wheres)
                               let roles = (from a in db.MngrRole.Where(x => !x.IsDeleted && x.MemberId == id) select a.RoleId)
                               select new RoleListDTO()
                               {
                                   ID = role.ID,
                                   RoleName = role.RoleName,
                                   Ischeck = roles.Count(x => x == role.ID) > 0
                               }).ToList();
                return allrole;
            }
        }
        public List<MenuModuleListDTO> LoadModuleList(string RoleId, LoginUserDTO loginUserDTO)
        {

            var dbset = db.Set<SysModule>();
            var em = Guid.Empty.ToString();
            var roldids = (from a in db.MngrRole.Where(x => x.MemberId == loginUserDTO.ID) select a).Select(x => x.RoleId).ToList();
            var sysroid = ("1cce4cc6-3889-42eb-8b09-74f475480ac6");//超级管理员角色
            var wheres = PredicateBuilder.True<MenuModuleListDTO>();
            var moduleid = loginUserDTO.UserActionList.Select(x => x.ModuleID).ToList();
            var moduleidpid = (from a in db.SysModule.Where(x => moduleid.Contains(x.ID)) select a).Select(x => x.PID).ToList();
            var bq = (from b in dbset.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted)
                      let ModuleActions = from modu in db.SysModuleAction.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted && x.ModuleID == b.ID) select modu
                      let c = (from c in dbset.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted && x.PID == b.ID)
                               let ModuleActions = from modu in db.SysModuleAction.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted && x.ModuleID == c.ID) select modu
                               select new model1
                               {
                                   ModuleName = c.ModuleName,
                                   ID = c.ID,
                                   ModuleActions = ModuleActions
                               })
                      select new model2
                      {
                          ModuleName = b.ModuleName,
                          ID = b.ID,
                          ModuleActions = ModuleActions,
                          c = c,
                          PID = b.PID
                      }).AsNoTracking().ToList();


            var bq2 = (from b in dbset.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted && x.PID == em)
                       let ModuleActions = from modu in db.SysModuleAction.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted && x.ModuleID == b.ID) select modu
                       let c = (from c in dbset.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted && x.ID == b.ID)
                                let ModuleActions = from modu in db.SysModuleAction.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted && x.ModuleID == c.ID) select modu
                                select new model1
                                {
                                    ModuleName = c.ModuleName,
                                    ID = c.ID,
                                    ModuleActions = ModuleActions
                                })
                       where ModuleActions.Count() > 0
                       select new model2
                       {
                           ModuleName = b.ModuleName,
                           ID = b.ID,
                           ModuleActions = ModuleActions,
                           c = c,
                           PID = b.PID
                       }).AsNoTracking().ToList();
            bq.AddRange(bq2);

            var query = (from a in dbset.OrderBy(x => x.OrderID).Where(x => !x.IsDeleted && x.PID == em)

                         select new MenuModuleListDTO()
                         {
                             ModuleName = a.ModuleName,
                             ID = a.ID

                         });
            var result = query.ToList();
            result.ForEach(a =>
            {
                if (roldids.Exists(x => x == sysroid))
                {

                    if (bq.Exists(x => x.ID == a.ID && x.ModuleActions.Count() > 0 && x.c.Count() > 0))
                    {
                        a.ChildModule = bq.Where(x => x.ID == a.ID && x.ModuleActions.Count() > 0 && x.c.Count() > 0).ToList().Select(x => new MenuChildModuleListDTO()
                        {
                            ID = x.ID,
                            ModuleName = x.ModuleName,
                            ChildAction =
                         x.ModuleActions.OrderBy(y => y.OrderID)
                             .Where(y => !y.IsDeleted)
                             .Select(y => new MenuChildActionListDTO()
                             {
                                 ActionName = y.ActionName,
                                 ModuleId = y.ModuleID,
                                 ID = y.ID,
                                 IsCheck = false,
                                 Weight = y.Weight,
                                 IsMenu = y.ShowEnum
                             }).ToList(),
                        }).ToList();

                    }
                    else
                    {
                        a.ChildModule = bq.Where(x => x.PID == a.ID).ToList().Select(x => new MenuChildModuleListDTO()
                        {
                            ID = x.ID,
                            ModuleName = x.ModuleName,
                            ChildAction =
                        x.ModuleActions.OrderBy(y => y.OrderID)
                            .Where(y => !y.IsDeleted)
                            .Select(y => new MenuChildActionListDTO()
                            {
                                ActionName = y.ActionName,
                                ModuleId = y.ModuleID,
                                ID = y.ID,
                                IsCheck = false,
                                Weight = y.Weight,
                                IsMenu = y.ShowEnum
                            }).ToList(),
                            ThreeChildModule = x.c.ToList().Select(y => new MenuThreeChildModuleListDTO()
                            {
                                ModuleName = y.ModuleName,
                                ID = y.ID,
                                ChildAction =
                                    y.ModuleActions.OrderBy(z => z.OrderID)
                                        .Where(z => !z.IsDeleted)
                                        .Select(z => new MenuChildActionListDTO()
                                        {
                                            ActionName = z.ActionName,
                                            ModuleId = z.ModuleID,
                                            ID = z.ID,
                                            IsCheck = false,
                                            Weight = z.Weight,
                                            IsMenu = z.ShowEnum
                                        }).ToList(),
                            }).ToList()
                        }).ToList();
                    }
                }
                else
                {
                    a.ChildModule = bq.Where(x => x.PID == a.ID && moduleid.Contains(x.ID)).ToList().Select(x => new MenuChildModuleListDTO()
                    {
                        ModuleName = x.ModuleName,
                        ID = x.ID,
                        ChildAction =
                                          x.ModuleActions.OrderBy(y => y.OrderID)
                                              .Where(y => !y.IsDeleted)
                                              .Select(y => new MenuChildActionListDTO()
                                              {
                                                  ActionName = y.ActionName,
                                                  ModuleId = y.ModuleID,
                                                  ID = y.ID,
                                                  IsCheck = false,
                                                  Weight = y.Weight,
                                                  IsMenu = y.ShowEnum
                                              }).ToList(),
                        ThreeChildModule = x.c.ToList().Select(y => new MenuThreeChildModuleListDTO()
                        {
                            ModuleName = y.ModuleName,
                            ID = y.ID,
                            ChildAction =
                                y.ModuleActions.OrderBy(z => z.OrderID)
                                    .Where(z => !z.IsDeleted)
                                    .Select(z => new MenuChildActionListDTO()
                                    {
                                        ActionName = z.ActionName,
                                        ModuleId = z.ModuleID,
                                        ID = z.ID,
                                        IsCheck = false,
                                        Weight = z.Weight,
                                        IsMenu = z.ShowEnum
                                    }).ToList(),
                        }).ToList()
                    }).ToList();
                }
            });
            if (!string.IsNullOrEmpty(RoleId))
            {
                var roleids = RoleId.Split(',').ToList();
                var roleList =
                    (from a in db.SysRole.Where(x => !x.IsDeleted && roleids.Contains(x.ID))
                     let RoleActions = from roleActions in db.SysRoleAction.Where(x => x.RoleID == a.ID) select roleActions
                     select new model3
                     {
                         RoleActions = RoleActions
                     }).ToList();
                result.ForEach(x => x.ChildModule.ForEach(y =>
                {
                    if (y.ChildAction != null && y.ChildAction.Any())
                    {

                        y.ChildAction.ForEach(z =>
                        {
                            var ischeck = false;
                            roleList.ForEach(r =>
                            {
                                r.RoleActions.ToList()?.ForEach(m =>
                                {
                                    if (z.ModuleId == m.ModuleID)
                                    {
                                        z.IsCheck = ((m.Weight & z.Weight) == z.Weight);
                                        if (z.IsCheck)
                                        {
                                            ischeck = true;
                                        }
                                    }
                                    if (z.ModuleId == m.ModuleID)
                                    {
                                        z.IsCheck = ischeck;
                                    }

                                });

                            });

                        });
                    }
                    else if (y.ThreeChildModule != null && y.ThreeChildModule.Any())
                    {
                        y.ThreeChildModule.ToList().ForEach(z =>
                        {
                            if (z.ChildAction != null && z.ChildAction.Any())
                            {

                                z.ChildAction.ToList().ForEach(n =>
                                {
                                    var ischeck = false;
                                    roleList.ForEach(r =>
                                    {
                                        r.RoleActions.ToList().ForEach(m =>
                                        {
                                            if (n.ModuleId == m.ModuleID)
                                            {
                                                n.IsCheck = ((m.Weight & n.Weight) == n.Weight);
                                                if (n.IsCheck)
                                                {
                                                    ischeck = true;
                                                }
                                            }
                                            if (n.ModuleId == m.ModuleID)
                                            {
                                                n.IsCheck = ischeck;
                                            }
                                        });

                                    });

                                });
                            }
                        });
                    }
                }));
            }

            if (loginUserDTO.CpnId != "system")
            {
                //返回当前企业用户包含的角色
                var cpnresult = result.Where(a => moduleidpid.Contains(a.ID)).ToList();
                return cpnresult;
            }
            return result;
        }
        /// <summary>
        /// 判断角色下是否还包含用户信息
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public bool ExistsRoleByRoleId(IEnumerable<string> ids)
        {
            return (from a in db.SysRole.Where(x => !x.IsDeleted && ids.Contains(x.ID))
                    join b in db.MngrRole.Where(x => !x.IsDeleted) on a.ID equals b.RoleId
                    join c in db.MngrBaseInfo.Where(x => !x.IsDeleted) on b.MemberId equals c.ID
                    select c.ID
                ).Any();
        }

    

        public Dictionary<string, object> GetAllAct(LoginUserDTO loginUserDTO)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}
